package com.storm.lib.net.socket.codec;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.Deflater;


import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.AttributeKey;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolEncoder;
import org.apache.mina.filter.codec.ProtocolEncoderOutput;

import com.storm.lib.util.ByteUtil;


import flex.messaging.io.SerializationContext;
import flex.messaging.io.amf.Amf3Output;

/**
 * 
 * 类功能:编码器
 * @author johnny
 * @version 2011-8-9
 */
public class AMF3Encoder implements ProtocolEncoder {
	/**
	 * 总计编码数量
	 */
	//public static int totalEncoder=0;
	/**
	 * 缓存大小
	 */
	//同屏500人的大小
	private static int cachesize = 8192;
	private final AttributeKey DEFLATER = new AttributeKey(getClass(), "deflater");	
	private final SerializationContext context = new SerializationContext();

	public void dispose(IoSession session) throws Exception {
//		amf3out.close();
	}

	public void encode(IoSession session, Object message,ProtocolEncoderOutput out) throws Exception {
		IoBuffer buffer;
		
		if (message instanceof String) {
//			System.out.println(message);
			out.write(IoBuffer.wrap(message.toString().getBytes()));
			
//			byte[] bytes = ((String) message).getBytes("UTF-8");
//			buffer = IoBuffer.allocate(bytes.length/* + 1*/);
//			buffer.put(bytes);
//			buffer.put((byte) 0x0);
//			buffer.flip();
//			out.write(buffer);
		}else{
			
			Amf3Output amf3out = new Amf3Output(context);
			ByteArrayOutputStream stream = new ByteArrayOutputStream();
			amf3out.setOutputStream(stream);
			amf3out.writeObject(message);		
			amf3out.flush();
			byte bodyBytes[] = compress(session,stream.toByteArray());
			byte[] headerBytes = ByteUtil.int2Byte(bodyBytes.length);
			ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(bodyBytes.length+4);
			byteArrayOutputStream.write(headerBytes,0,headerBytes.length);
			byteArrayOutputStream.write(bodyBytes,0,bodyBytes.length);
			byte[] resultBytes  = byteArrayOutputStream.toByteArray();
			
			buffer = IoBuffer.allocate(resultBytes.length,false);
			buffer.put(resultBytes);
			buffer.flip();
			out.write(buffer);
			buffer.free();
			amf3out.close();
		}
		//totalEncoder++;
		//System.out.println("服务端TOTAL ENCODE"+totalEncoder);
	}
	
	private byte[] compress(IoSession session,byte[] inputs){
		Deflater deflater = (Deflater)session.getAttribute(DEFLATER);
		if(deflater == null){
			deflater = new Deflater();
			session.setAttribute(DEFLATER,deflater);
		}
		deflater.reset();
		deflater.setInput(inputs);
		deflater.finish();
		byte outputs[] = new byte[0]; 
		ByteArrayOutputStream stream = new ByteArrayOutputStream(inputs.length); 
		byte[] bytes = new byte[cachesize];
		int value; 
		while(!deflater.finished()){
			value = deflater.deflate(bytes);
			stream.write(bytes,0, value);			
		}
		outputs = stream.toByteArray();
		try {
			stream.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return outputs;
	}
	

}
